Skip to content

Conversation

@kaeizen
Copy link
Contributor

@kaeizen kaeizen commented Sep 10, 2025

fixes #3575

Summary by CodeRabbit

  • Refactor
    • Improved SortablePicker by adding ref support, enabling smoother integration with parent components and future extensibility.
    • Modularized the color item picker into a dedicated component, simplifying structure and promoting reuse across the app.
    • Updated color picker integration to maintain existing behavior while improving clarity and maintainability.
    • No user-facing changes expected; these updates enhance reliability and consistency behind the scenes.

@coderabbitai
Copy link

coderabbitai bot commented Sep 10, 2025

Walkthrough

Forwarded refs were added to SortablePicker by converting it to forwardRef and attaching the ref to its root element. The color picker integration was refactored by extracting a dedicated ItemPickerColor component and wiring ColorPickers to use it, preserving value updates via onChange with color merging.

Changes

Cohort / File(s) Summary
SortablePicker ref forwarding
src/components/sortable-picker/index.js
Converted component to forwardRef((props, ref) => ...), removed ref from props destructuring, and attached the forwarded ref to the root container.
Global color picker refactor
src/plugins/global-settings/colors/color-picker.js
Introduced ItemPickerColor wrapper rendering ColorPicker with enableAlpha: true; replaced inline item picker within ColorPickers by passing ItemPickerColor to SortablePicker’s ItemPicker prop; updates item via onChange({ ...item, color: value }).

Sequence Diagram(s)

sequenceDiagram
  autonumber
  participant U as User
  participant SP as SortablePicker (forwardRef)
  participant IPC as ItemPickerColor
  participant CP as ColorPicker
  participant P as Parent (Global Colors UI)

  U->>SP: Open item editor
  SP->>IPC: Render ItemPicker (with item, onChange)
  IPC->>CP: Render ColorPicker(color=item.color, enableAlpha=true)
  U->>CP: Drag/select color
  CP-->>IPC: onChange(value)
  IPC-->>SP: onChange({ ...item, color: value })
  SP-->>P: Propagate updated items

  note over SP,P: SP exposes root DOM via forwarded ref (outside-click/drag handling)
Loading

Estimated code review effort

🎯 2 (Simple) | ⏱️ ~10 minutes

Poem

I nudge the hues with gentle paw,
A picker pops—no stutter, no flaw.
With refs now flowing, clicks obey,
Drag the rainbow, then tuck away.
Bugs hop off; I sip my tea—
Colors sorted, joyfully. 🐇🌈

Pre-merge checks and finishing touches

❌ Failed checks (1 inconclusive)
Check name Status Explanation Resolution
Linked Issues Check ❓ Inconclusive The changes show SortablePicker was converted to forwardRef and the color picker now uses an ItemPickerColor wrapper, which plausibly enable proper pointer interactions and allow outside-click detection, but the summaries do not show where the forwarded ref is consumed or any explicit outside-click handler or tests, so I cannot conclusively verify that both behaviors (dragging inside the gradient and closing on outside click) are implemented and validated. Please supply the code that consumes the forwarded ref to implement outside-click detection or provide manual/automated test results demonstrating that (1) dragging in the gradient works and (2) clicking outside closes the picker, or add tests that assert these behaviors.
✅ Passed checks (4 passed)
Check name Status Explanation
Description Check ✅ Passed Check skipped - CodeRabbit’s high-level summary is enabled.
Title Check ✅ Passed The PR title "Fix (Global Colors): fix dragging in color picker" is concise and directly references the main user-facing problem (dragging in the color picker), so it is relevant and readable; however it does not mention the linked issue’s second concern (closing the picker on outside click).
Out of Scope Changes Check ✅ Passed All modified files (SortablePicker and the color-picker wrapper) are directly related to the reported issue and there are no unrelated files changed; the signature change to forwardRef appears to be a targeted, in-scope modification to enable the intended behavior.
Docstring Coverage ✅ Passed No functions found in the changes. Docstring coverage check skipped.
✨ Finishing touches
  • 📝 Generate Docstrings
🧪 Generate unit tests
  • Create PR with unit tests
  • Post copyable unit tests in a comment
  • Commit unit tests in branch fix/3575-global-color-picker-dragging

Tip

👮 Agentic pre-merge checks are now available in preview!

Pro plan users can now enable pre-merge checks in their settings to enforce checklists before merging PRs.

  • Built-in checks – Quickly apply ready-made checks to enforce title conventions, require pull request descriptions that follow templates, validate linked issues for compliance, and more.
  • Custom agentic checks – Define your own rules using CodeRabbit’s advanced agentic capabilities to enforce organization-specific policies and workflows. For example, you can instruct CodeRabbit’s agent to verify that API documentation is updated whenever API schema files are modified in a PR. Note: Upto 5 custom checks are currently allowed during the preview period. Pricing for this feature will be announced in a few weeks.

Please see the documentation for more information.

Example:

reviews:
  pre_merge_checks:
    custom_checks:
      - name: "Undocumented Breaking Changes"
        mode: "warning"
        instructions: |
          Pass/fail criteria: All breaking changes to public APIs, CLI flags, environment variables, configuration keys, database schemas, or HTTP/GraphQL endpoints must be documented in the "Breaking Change" section of the PR description and in CHANGELOG.md. Exclude purely internal or private changes (e.g., code not exported from package entry points or explicitly marked as internal).

Please share your feedback with us on this Discord post.


Thanks for using CodeRabbit! It's free for OSS, and your support helps us grow. If you like it, consider giving us a shout-out.

❤️ Share

Comment @coderabbitai help to get the list of available commands and usage tips.

@github-actions
Copy link

github-actions bot commented Sep 10, 2025

🤖 Pull request artifacts

file commit
pr3590-stackable-3590-merge.zip 646a6d4

github-actions bot added a commit that referenced this pull request Sep 10, 2025
Copy link

@coderabbitai coderabbitai bot left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Actionable comments posted: 4

Caution

Some comments are outside the diff and can’t be posted inline due to platform limitations.

⚠️ Outside diff range comments (1)
src/plugins/global-settings/colors/color-picker.js (1)

128-132: Auto-open of the newly added color likely no-ops due to missing forwardRef in SortablePicker.

ref passed to <SortablePicker ref={ ref } /> won’t reach the inner <div ref={ ref }> without forwardRef. As a result, ref.current?.querySelector(...).click() won’t run. See proposed forwardRef fix in src/components/sortable-picker/index.js.

🧹 Nitpick comments (2)
src/plugins/global-settings/colors/color-picker.js (1)

27-40: Good fix: exporting the picker component restores drag behavior. Also keep rgb in sync.

LGTM on exporting ItemPickerColor to avoid the drag regression. However, updates only set item.color and leave item.rgb stale. If other UI relies on rgb, this will desync on drag.

Apply:

 export const ItemPickerColor = ( { item, onChange } ) => {
   return <div className="stk-color-palette-control__popover-content">
     <ColorPicker
-      onChange={ value => onChange( {
-        ...item,
-        color: value,
-      } ) }
+      onChange={ value => onChange( {
+        ...item,
+        color: value,
+        rgb: getRgb( value ),
+      } ) }
       color={ item.color }
       enableAlpha={ true }
     />
   </div>
 }
src/components/sortable-picker/index.js (1)

23-23: Decouple from plugin-specific registry.

Importing ITEM_PICKER here ties components to plugin code (via util). Prefer a resolver prop with a safe fallback.

Apply:

-import { ITEM_PICKER } from './util'
+import { ITEM_PICKER } from './util' // keep for backward compat, but prefer props.itemPickerResolver

Then in renderContent (see next comment) use props.itemPickerResolver || ITEM_PICKER.
Also add a default prop:

 SortablePicker.defaultProps = {
   className: '',
   label: '',
   onReset: () => {},
+  itemPickerResolver: {},
 }
📜 Review details

Configuration used: CodeRabbit UI

Review profile: CHILL

Plan: Pro

📥 Commits

Reviewing files that changed from the base of the PR and between fb2381e and 7702cee.

📒 Files selected for processing (3)
  • src/components/sortable-picker/index.js (2 hunks)
  • src/components/sortable-picker/util.js (1 hunks)
  • src/plugins/global-settings/colors/color-picker.js (2 hunks)
🧰 Additional context used
🧬 Code graph analysis (2)
src/components/sortable-picker/util.js (1)
src/plugins/global-settings/colors/color-picker.js (2)
  • ItemPickerColor (29-40)
  • ItemPickerColor (29-40)
src/components/sortable-picker/index.js (1)
src/components/sortable-picker/util.js (2)
  • ITEM_PICKER (3-5)
  • ITEM_PICKER (3-5)
⏰ Context from checks skipped due to timeout of 90000ms. You can increase the timeout in your CodeRabbit configuration to a maximum of 15 minutes (900000ms). (7)
  • GitHub Check: build
  • GitHub Check: PHP 8.2 and WP 6.6.2
  • GitHub Check: PHP 8.2 and WP 6.7.2
  • GitHub Check: PHP 8.2 and WP 6.5.5
  • GitHub Check: PHP 8.2 and WP latest
  • GitHub Check: PHP 7.3 and WP 6.5.5
  • GitHub Check: PHP 7.3 and WP latest

github-actions bot added a commit that referenced this pull request Sep 16, 2025
Copy link

@coderabbitai coderabbitai bot left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Actionable comments posted: 0

🧹 Nitpick comments (3)
src/components/sortable-picker/index.js (3)

48-61: Ref‑forwarding conversion looks good.

Signature switched to forwardRef((props, ref)) with correct prop destructuring. No behavior change otherwise.

Apply a tiny DX tweak so the component shows a readable name in React DevTools:

 } )
 
+SortablePicker.displayName = 'SortablePicker'
+
 SortablePicker.defaultProps = {

72-85: Guard against null AddItemPopover to avoid runtime errors when dropdownOnAdd is true.

If AddItemPopover is null and someone toggles the dropdown (e.g., via keyboard), <AddItemPopover .../> will throw.

Suggested change:

-			{ enableAddItem && <Dropdown
+			{ enableAddItem && ( !dropdownOnAdd || AddItemPopover ) && <Dropdown
 				popoverProps={ addItemPopoverProps }
 				renderToggle={ ( { onToggle, isOpen } ) => (
 					<Button
 						className="ugb-global-settings-color-picker__add-button"
 						onClick={ dropdownOnAdd ? onToggle : handleAddItem }
 						icon="plus-alt2"
 						aria-expanded={ isOpen }
 					/>
 				) }
-				renderContent={ ( { onClose } ) => (
-					<AddItemPopover onClose={ onClose } onChange={ handleAddItem } />
-				) }
+				renderContent={ ( { onClose } ) =>
+					AddItemPopover ? (
+						<AddItemPopover onClose={ onClose } onChange={ handleAddItem } />
+					) : null
+				}
 			/> }

119-133: Prefer stable keys over array indices.

Using index as key will cause unnecessary remounts during reordering. Use a stable identifier (e.g., item.slug) if available.

📜 Review details

Configuration used: CodeRabbit UI

Review profile: CHILL

Plan: Pro

📥 Commits

Reviewing files that changed from the base of the PR and between 7702cee and 646a6d4.

📒 Files selected for processing (2)
  • src/components/sortable-picker/index.js (3 hunks)
  • src/plugins/global-settings/colors/color-picker.js (2 hunks)
🧰 Additional context used
🧬 Code graph analysis (2)
src/plugins/global-settings/colors/color-picker.js (1)
src/components/color-palette-control/index.js (2)
  • value (162-162)
  • onChange (163-163)
src/components/sortable-picker/index.js (2)
src/plugins/global-settings/colors/color-picker.js (1)
  • ref (41-41)
src/plugins/global-settings/color-schemes/color-scheme-picker.js (1)
  • ref (86-86)
⏰ Context from checks skipped due to timeout of 90000ms. You can increase the timeout in your CodeRabbit configuration to a maximum of 15 minutes (900000ms). (6)
  • GitHub Check: PHP 7.3 and WP latest
  • GitHub Check: PHP 8.2 and WP 6.7.2
  • GitHub Check: PHP 8.2 and WP latest
  • GitHub Check: PHP 8.2 and WP 6.6.2
  • GitHub Check: PHP 7.3 and WP 6.5.5
  • GitHub Check: PHP 8.2 and WP 6.5.5
🔇 Additional comments (4)
src/components/sortable-picker/index.js (2)

20-22: Importing forwardRef is correct and necessary.

Good addition to enable ref forwarding.


86-93: Attaching the forwarded ref to the container is appropriate.

This exposes the correct subtree for the “open newly added color” click via querySelector.

Manual check:

  • Add a new color; confirm the picker opens automatically.
  • Ensure ref.current is a DOM node and querySelector finds the last .stk-global-settings-color-picker__color-indicator-wrapper dropdown.
src/plugins/global-settings/colors/color-picker.js (2)

27-38: ItemPickerColor wiring is correct; uses ColorPicker’s string onChange API.

@wordpress/components ColorPicker fires onChange with a hex/hex8 string; storing it in item.color is appropriate. Consider accepting and passing through onClose for future needs (e.g., committing on close), but not required here.

Quick UX check:

  • Drag inside the gradient and alpha slider; color updates continuously without losing focus.
  • Press Esc; popover closes (Dropdown handles it).

160-160: Passing ItemPickerColor directly simplifies integration and fixes drag interactions.

This avoids dynamic string resolution and ensures the picker remains interactive for click‑and‑drag.

Acceptance criteria to verify against Issue #3575:

  • You can click‑and‑drag inside the color gradient to update the color.
  • Clicking anywhere outside the picker closes the panel automatically.

If either fails, ping and I’ll help trace the event handling.

@bfintal bfintal merged commit 61f9fe7 into develop Sep 17, 2025
8 of 9 checks passed
@bfintal bfintal deleted the fix/3575-global-color-picker-dragging branch September 17, 2025 09:26
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

Global color picker - cannot drag the color picker and close on outside click

3 participants